#include "Source/Application.h"
#include "Source/IO/File.h"
#include "Source/Globals.h"
#include "Source/Sprite.h"
#include "Source/Texture.h"
#include "Source/utils.h"
#include "stdio.h"
#include "Source/Globals.h"
#include "json.h"
#include <string>
#include <boost/lexical_cast.hpp>

DEFINE_SINGLETON(Application)

void Application::Initialize()
{
	m_bPaused= false;
	m_bIsRunning =false;
	m_uDt = 0;
	m_uLastFrameTime = 0;
	m_uAnimationClock = 0;
	m_screenWidth = 0;
	m_screenHeight = 0;
}

void Application::Destroy()
{
	//Destroy window
	SDL_DestroyWindow( m_window );
	m_window = NULL;

	//Quit SDL subsystems
	SDL_Quit();
}

void Application::Start()
{
	Initialize();

	if( SDL_Init( SDL_INIT_VIDEO ) < 0 )
	{
		//Display error
	}	
	else
	{
		LoadConfig();
		//Create window
		m_window = SDL_CreateWindow( "SDL Tutorial", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, m_screenWidth, m_screenHeight, SDL_WINDOW_SHOWN );
		if( m_window == NULL )
		{
			//Display error
		}
		else
		{
			//Get window surface
			m_screen = SDL_GetWindowSurface( m_window );
		}
	}
	
	Sprite* theSprite = new Sprite();
	theSprite->LoadTexture("../../Data/Art/Sprites/Sprite1.spr");
	//theSprite->SaveTexture("../../Data/Art/Sprites/Sprite1.spr");


	SDL_UpdateWindowSurface(m_window);

	m_bIsRunning = true;
	while (true)
	{
		//Read Keyboard Input (TODO: Implement Keyboard class)
		SDL_Event ev;
		SDL_PollEvent(&ev);

		switch(ev.type)
		{
			case SDL_KEYDOWN: //Check for pressed buttons
				{

					switch(ev.key.keysym.sym) //Manage the input
					{
						case SDLK_ESCAPE:
						{
							Exit();
							break;
						}

						case SDLK_p:
						{
							Pause();
							break;
						}

						case SDLK_r:
						{
							Resume();
							break;
						}

						case SDLK_SPACE:
						{
						}
					}
					break;
				}

		}

		if(!m_bIsRunning)
			break;

		//Update next frame
		Uint32 currFrame = SDL_GetTicks();
		m_uDt += currFrame - m_uLastFrameTime;
		m_uLastFrameTime = currFrame;
		if(m_uDt>G_MIN_FRAME_TIME && !m_bPaused)
		{
			Update();
			theSprite->Draw();
			SDL_UpdateWindowSurface(m_window);
			m_uDt = 0;
		}
	}

}
void Application::Exit()
{
	SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_WARNING, "Closing STEAMPUNK", "Steampunk will now close!", NULL); 
	m_bIsRunning = false;

	Destroy();
}

void Application::LoadConfig()
{
	CL_File* file = CL_File::Open(G_APP_CFG_FILENAME_FULL, E_FileModes_ReadText);
	std::string jsonDoc="";
	while(!file->IsEOF())
	{
		std::string line;
		file->ReadLine(line);
		jsonDoc.append(line);
	}

	file->Close();
	delete file;
	file=NULL;

	Json::Value data;
	Json::Reader reader;
	reader.parse(jsonDoc, data, false);

	m_screenWidth = data["screen_width"].asInt();
	m_screenHeight = data["screen_height"].asInt();
	//TODO: Create a config class
}

void Application::Update()
{
	SDL_FillRect(m_screen, NULL, SDL_MapRGB(m_screen->format, 0, 0, 0) );
	SDL_UpdateWindowSurface(m_window);
}

void Application::Pause()
{
	m_bPaused = true;
}

void Application::Resume()
{
	m_bPaused = false;
}

SDL_Surface* Application::GetScreen()
{
	return m_screen;
}